home *** CD-ROM | disk | FTP | other *** search
/ Amiga Plus 2004 #11 / Amiga Plus CD - 2004 - No. 11.iso / AmiSoft / Misc / emu / p-interp.lha / p-interp-0.5 / Term.c < prev    next >
C/C++ Source or Header  |  2004-08-03  |  11KB  |  514 lines

  1. /*
  2.  
  3.   P-Code interpreter (to run the apple pascal system)
  4.   Copyright (C) 2000 Mario Klebsch
  5.  
  6.   This program is free software; you can redistribute it and/or modify
  7.   it under the terms of the GNU General Public License as published by
  8.   the Free Software Foundation; either version 2 of the License, or
  9.   (at your option) any later version.
  10.  
  11.   This program is distributed in the hope that it will be useful,
  12.   but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14.   GNU General Public License for more details.
  15.  
  16.   You should have received a copy of the GNU General Public License
  17.   along with this program; if not, write to the Free Software
  18.   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  19.  
  20.   $Log: Term.c,v $
  21.   Revision 1.5  2001/06/07 20:03:10  mario
  22.   Anfang der Integration von Amiga-Patches, die Stefan A. Haubenthal
  23.   <polluks@web.de> mir geschickt hat. Es ist aber erst der Ausgabe-Teil
  24.   fertig, die Anpassungen der Eingaberoutinen sind daher noch nicht
  25.   integriert.
  26.  
  27.   Revision 1.4  2001/05/26 15:13:29  mario
  28.   Diverse kleine Fehler behoben, fehlende #includes, Labels ohne Statement
  29.   dahinter, ...
  30.  
  31.   Revision 1.3  2001/05/20 20:14:40  mario
  32.   Neues Gerät PRINTER: implementiert
  33.  
  34.   Revision 1.2  2001/05/20 13:12:02  mario
  35.   CVS-Idents und Logs eingefügt
  36.  
  37.  
  38. */
  39.  
  40. #ident "$Id: Term.c,v 1.5 2001/06/07 20:03:10 mario Exp $";
  41.  
  42. #include <fcntl.h>
  43. #include <stdlib.h>
  44. #include <stdio.h>
  45. #include <unistd.h>
  46. #include <string.h>
  47. #ifndef _AMIGA
  48. #include <curses.h>
  49. #include <term.h>
  50. #include <termios.h>
  51. #include <assert.h>
  52. #include <sys/time.h>
  53. #include <sys/types.h>
  54. #include <sys/stat.h>
  55. #include <sys/socket.h>
  56. #include <netinet/in.h>
  57. #endif
  58.  
  59. #include "psystem.h"
  60. #include "Memory.h"
  61. #include "Term.h"
  62.  
  63. static int BatchMode=0;
  64. static int TermIn=-1;
  65. static int TermOut=-1;
  66. #ifndef _AMIGA
  67. struct termios    OldTerm;
  68. #else
  69. static char *clr_eol        = "\233K";
  70. static char *clr_eos        = "\233J";
  71. static char *clear_screen   = "\2332J";
  72. static char *insert_line    = "\233L";
  73. #if 0
  74. static char *cursor_home    = "\233H";
  75. #else
  76. static char *cursor_home    = "\233;H"; /* MorphOS */
  77. #endif
  78. static char *cursor_up      = "\233A";
  79. static char *cursor_right   = "\233C";
  80. static char *cursor_address = "\233%d;%dH";
  81. #define tgoto(cursor_address, x, y) s="",sprintf(s, cursor_address, y+1, x+1)
  82. #endif /* _AMIGA */
  83. /*
  84.  
  85.   erase line=0
  86.   erase to end of screen=11
  87.   erase screen=12
  88.   insert line=22
  89.   move cursor home=25
  90.   move cursor right=28
  91.   erase to end of line=29
  92.   gotoxy=30
  93.   move cursor up=31
  94.  
  95.  */
  96.  
  97. void TermWrite(char ch, word Mode)
  98. {
  99.   static int state=0;
  100.   static int x;
  101.   int         y;
  102.   char         *s;
  103.  
  104.   switch(state)
  105.     {
  106.     case 0:
  107.       switch(ch)
  108.     {
  109.     case 0:                /* erase line ???            */
  110.       if (!(Mode&0x8))
  111.         ;
  112.       else
  113.         write(TermOut, &ch, 1);
  114.       break;
  115.     case 7:
  116.       if (!BatchMode)
  117.         write(TermOut, &ch, 1);
  118.       break;
  119.     case 11:            /* erase to end of screen        */
  120.       if (!BatchMode && clr_eos)
  121.         write(TermOut, clr_eos, strlen(clr_eos));
  122.       break;
  123.     case 12:            /* erase screen                */
  124.       if (!BatchMode && clear_screen)
  125.         write(TermOut, clear_screen, strlen(clear_screen));
  126.       break;
  127.     case 13:            /* carriage return            */
  128.       if (!(Mode&0x4))
  129.         if (!BatchMode)
  130.           write(TermOut,"\r\n", 2);
  131.         else
  132.           write(TermOut,"\n", 1);
  133.       else
  134.         write(TermOut, &ch, 1);
  135.       break;
  136.     case 16:            /* DLE prefix                */
  137.       if (!(Mode&0x8))
  138.         state=3;
  139.       break;
  140.     case 22:
  141.       if (!BatchMode && insert_line)
  142.         write(TermOut, insert_line, strlen(insert_line));
  143.       break;
  144.     case 25:            /* move cursor home            */
  145.       if (!BatchMode && cursor_home)
  146.         write(TermOut, cursor_home, strlen(cursor_home));
  147.       else
  148.         write(TermOut,"\n", 1);
  149.       break;
  150.     case 28:            /* move cursor right            */
  151.       if (!BatchMode && cursor_right)
  152.         write(TermOut, cursor_right, strlen(cursor_right));
  153.       break;
  154.     case 29:            /* erase to end of line            */
  155.       if (!BatchMode && clr_eol)
  156.         write(TermOut, clr_eol, strlen(clr_eol));
  157.       break;
  158.     case 30:            /* gotoxy                */
  159.       state=1;
  160.       break;
  161.     case 31:            /* move cursor up            */
  162.       if (!BatchMode && cursor_up)
  163.         write(TermOut, cursor_up, strlen(cursor_up));
  164.       break;
  165.     default:
  166.       write(TermOut, &ch, 1);
  167.       break;
  168.     }
  169.       break;
  170.     case 1:
  171.       x=ch-' ';
  172.       state=2;
  173.       break;
  174.     case 2:                /* gotoxy complete            */
  175.       y=ch-' ';
  176.       if (!BatchMode && cursor_address)
  177.     {
  178.       s=tgoto(cursor_address, x, y);
  179.       write(TermOut, s, strlen(s));
  180.     }
  181.       state=0;
  182.       break;
  183.     case 3:                /* char after DLE            */
  184.       ch -= 0x20;
  185.       while (ch--)
  186.     write(TermOut, " ", 1);
  187.       state=0;
  188.       break;
  189.     }
  190. }
  191.  
  192. #ifndef _AMIGA
  193. static struct translator
  194. {
  195.   struct translator    *Next;
  196.   char            *Pattern;
  197.   byte            Key;
  198.   void            (*Action)(byte);
  199. } *Keys=NULL;
  200.  
  201. static void AddKeyTranslation(byte Key, char *Pattern, void (*Action)(byte))
  202. {
  203.   struct translator    *NewKey=malloc(sizeof(struct translator));
  204.   assert(NewKey);
  205.   NewKey->Key     = Key;
  206.   NewKey->Pattern = Pattern;
  207.   NewKey->Action  = Action;
  208.   NewKey->Next    = Keys;
  209.   Keys=NewKey;
  210. }
  211.  
  212. char TermRead(void)
  213. {
  214.   unsigned char    ch;
  215.  
  216.   static int    state=0;
  217.   static int    BufIdx=0;
  218.   static char    Buffer[10];
  219.  
  220.   if (state==0)
  221.     while (1)
  222.       {
  223.     fd_set        fds;
  224.     struct timeval    tv;
  225.     FD_ZERO(&fds);
  226.     FD_SET(TermIn, &fds);
  227.     tv.tv_sec = 0;
  228.     tv.tv_usec = 25000;
  229.     
  230.     if (select(TermIn+1, &fds, NULL, NULL, BufIdx?&tv:NULL)>0)
  231.       {                /* Ein Zeichen ist verfügbar        */
  232.         struct translator *t;
  233.         int    Match=0;
  234.  
  235.         if (read(TermIn, &ch, 1)<1)    /* Lesen und in Puffer speichern    */
  236.           if (BatchMode)
  237.         exit(0);
  238.  
  239. #ifndef XXX
  240.         if (ch=='\0')    /* XXX Quick-Hack :-( */
  241.           continue;
  242. #endif
  243.  
  244.         Buffer[BufIdx++]=ch;
  245.         for (t=Keys; t; t=t->Next)
  246.           {
  247.         int    i;
  248.         for (i=0; i< BufIdx; i++)
  249.           if (Buffer[i] != t->Pattern[i])
  250.             goto next;
  251.         if (!(t->Pattern[BufIdx]))    /* full Pattern match */
  252.           {
  253.             BufIdx=0;
  254.             return (t->Key);
  255.           }
  256.         Match=1;
  257.         break;
  258.           next:
  259.         ;
  260.           }
  261.         if (!Match)
  262.           goto ret;
  263.       }
  264.     else                /* Timeout                */
  265.       {
  266.       ret:
  267.         if (BufIdx>1)
  268.           state=1;
  269.         else
  270.           BufIdx=0;
  271.         return(Buffer[0]);
  272.       }
  273.       }
  274.   else
  275.     {
  276.       ch=Buffer[state++];
  277.       if (state >=BufIdx)
  278.     {
  279.       state=0;
  280.       BufIdx=0;
  281.     }
  282.       return(ch);
  283.     }
  284. }
  285.  
  286. int TermStat(void)
  287. {
  288.   fd_set        fds;
  289.   struct timeval    tv;
  290.   FD_ZERO(&fds);
  291.   FD_SET(TermIn, &fds);
  292.   tv.tv_sec = 0;
  293.   tv.tv_usec = 0;
  294.     
  295.   if (select(TermIn+1, &fds, NULL, NULL, &tv)>0)
  296.     return(1);
  297.   else
  298.     return(0);
  299. }
  300.  
  301. static void OpenXTerm(void)
  302. {
  303.   int            i;
  304.   int            s;
  305.   struct sockaddr_in    addr;
  306.   char            Buffer[256];
  307.       
  308.   unsigned char        TelnetInit[]=
  309.   { 255, 253, 3,
  310.     255, 251, 3,
  311.     255, 251, 1
  312.   };
  313.  
  314.   if ((s=socket(PF_INET, SOCK_STREAM, 0))<0)
  315.     {
  316.       perror("socket()");
  317.       exit(1);
  318.     }
  319.   addr.sin_family=AF_INET;
  320.   addr.sin_addr.s_addr=htonl(INADDR_LOOPBACK);
  321.   addr.sin_port=htons(0);
  322.   if (bind(s, (struct sockaddr*)&addr, sizeof(addr))<0)
  323.     {
  324.       perror("bind()");
  325.       exit(1);
  326.     }
  327.   if (listen(s,1)<0)
  328.     {
  329.       perror("listen()");
  330.       exit(1);
  331.     }
  332.   i=sizeof(addr);
  333.   if (getsockname(s, (struct sockaddr*)&addr, &i)<0)
  334.     {
  335.       perror("getsockname()");
  336.       exit(1);
  337.     }
  338.   
  339.   snprintf(Buffer, sizeof(Buffer), "xterm -geometry 80x24 -e "
  340.        "telnet -E localhost %d&", ntohs(addr.sin_port));
  341.   system(Buffer);
  342.   
  343.   i=sizeof(addr);
  344.   if ((TermOut=accept(s, (struct sockaddr*)&addr, &i))<0)
  345.     {
  346.       perror("accept()");
  347.       exit(1);
  348.     }
  349.  
  350.   close(s);
  351.  
  352.   write(TermOut, TelnetInit, sizeof(TelnetInit));
  353.   for (i=0; i<sizeof(TelnetInit); i++)
  354.     read(TermOut, &s, 1);
  355. }
  356.  
  357. void TermOpen(int UseXTerm, int BatchFd)
  358. {
  359.   struct termios    NewTerm;
  360.  
  361.   if (BatchFd<0)
  362.     BatchMode=0;
  363.   else
  364.     {
  365.       BatchMode=1;
  366.       TermIn=BatchFd;
  367.     }
  368.  
  369.   if (UseXTerm)
  370.     {
  371.       OpenXTerm();
  372.       setupterm("xterm", TermOut, NULL);
  373.     }
  374.   else
  375.     {
  376.       if (BatchMode)
  377.     {
  378.       TermOut=1;
  379.       setupterm("dumb", TermOut, NULL);
  380.     }
  381.       else
  382.     {
  383.       if ((TermOut=open("/dev/tty", O_RDWR))<0)
  384.         {
  385.           perror("/dev/tty");
  386.           exit(1);
  387.         }
  388.       setupterm(NULL, TermOut, NULL);
  389.     }
  390.     }
  391.  
  392.   if (TermIn<0)
  393.     TermIn=TermOut;
  394.  
  395.   
  396.   if (BatchMode)
  397.     {
  398.       AddKeyTranslation('\r', "\n",  NULL);
  399.     }
  400.   else
  401.     {
  402.       tcgetattr(TermOut, &OldTerm);
  403.       NewTerm=OldTerm;
  404.       NewTerm.c_iflag &= ~(PARMRK | ISTRIP | INLCR | IGNCR | 
  405.                ICRNL | IUCLC | IXOFF | IXON);
  406.       NewTerm.c_oflag &= ~OPOST;
  407.       NewTerm.c_lflag &= ~(ISIG | ICANON | ECHO | ECHONL | IEXTEN);
  408.       NewTerm.c_cc[VMIN]=1;
  409.       NewTerm.c_cc[VTIME]=0;
  410.       tcsetattr(TermOut, TCSANOW, &NewTerm);
  411.  
  412.       if (init_1string)
  413.     write(TermOut, init_1string, strlen(init_1string));
  414.       if (init_2string)
  415.     write(TermOut, init_2string, strlen(init_2string));
  416.       if (init_3string)
  417.     write(TermOut, init_3string, strlen(init_3string));
  418.       if (enter_ca_mode)
  419.     write(TermOut, enter_ca_mode, strlen(enter_ca_mode));
  420.  
  421.       AddKeyTranslation(0x0b, "\033[A",  NULL);
  422.       AddKeyTranslation(0x0a, "\033[B",  NULL);
  423.       AddKeyTranslation(0x15, "\033[C",  NULL);
  424.       AddKeyTranslation(0x08, "\033[D",  NULL);
  425.  
  426.       AddKeyTranslation(0x0b, "\033[OA",  NULL);
  427.       AddKeyTranslation(0x0a, "\033[OB",  NULL);
  428.       AddKeyTranslation(0x15, "\033[OC",  NULL);
  429.       AddKeyTranslation(0x08, "\033[OD",  NULL);
  430.       
  431.       if (key_up)
  432.     AddKeyTranslation(0x0b, key_up,    NULL);
  433.       if (key_down)
  434.     AddKeyTranslation(0x0a, key_down,  NULL);
  435.       if (key_right)
  436.     AddKeyTranslation(0x15, key_right, NULL);
  437.       if (key_left)
  438.     AddKeyTranslation(0x08, key_left,  NULL);
  439.     }
  440. }
  441. #else /* _AMIGA */
  442. void TermClose(void)
  443. {
  444.   if (!BatchMode)
  445. #ifndef _AMIGA
  446.     {
  447.       write(TermOut,"\r\n",2);
  448.       if (exit_ca_mode)
  449.     write(TermOut, exit_ca_mode, strlen(exit_ca_mode));
  450.       if (reset_1string)
  451.     write(TermOut, reset_1string, strlen(reset_1string));
  452.       if (reset_2string)
  453.     write(TermOut, reset_2string, strlen(reset_2string));
  454.       if (reset_3string)
  455.     write(TermOut, reset_3string, strlen(reset_3string));
  456.       tcsetattr(TermOut, TCSANOW, &OldTerm);
  457.     }
  458. #else
  459.     rawcon(0);
  460. #endif
  461.   else
  462.     write(TermOut,"\n",1);
  463.   close(TermOut);
  464.   close(TermIn);
  465. }
  466.  
  467. void TermOpen(int UseXTerm, int BatchFd)
  468. {
  469.   if (BatchFd<0)
  470.     BatchMode=0;
  471.   else
  472.     {
  473.       BatchMode=1;
  474.       TermIn=BatchFd;
  475.     }
  476.  
  477.   if (UseXTerm)
  478.     {
  479.       TermOut=open("RAW:0/0/640/208/UCSD p-code interpreter", O_RDWR);
  480.     }
  481.   else
  482.     {
  483.       if (BatchMode)
  484.         {
  485.           TermOut=1;
  486.         }
  487.       else
  488.         {
  489.           TermOut=1;
  490.           TermIn=0;
  491.           rawcon(1);
  492.         }
  493.     }
  494.  
  495.   if (TermIn<0)
  496.     TermIn=TermOut;
  497. }
  498.  
  499. char TermRead(void)
  500. {
  501.   signed char    ch;
  502.  
  503.   if (read(TermIn, &ch, 1)<1)
  504.     if (BatchMode)
  505.       exit(0);
  506.   return ch;
  507. }
  508.  
  509. int TermStat(void)
  510. {
  511.   return WaitForChar(Input(),1);
  512. }
  513. #endif /* _AMIGA */
  514.